home *** CD-ROM | disk | FTP | other *** search
- /*
- * Object to peck on a remote network weather service.
- *
- * Michael Hawley
- * MIT Media Laboratory
- * 20 Ames Street
- * Cambridge, MA 02139
- * mike@media-lab.mit.edu
- * Copyright (c) 1991 MIT Media Laboratory
- * Burn before reading! This means you!!
- *
- * Please forward any comments/revisions.
- * Keep in mind that this was a one-day knock off;
- * much of the complexity is due to the fact that
- * we have to parse a telnet conversation that was
- * never intended for such.
- */
-
- #import "Storm.h"
- #import "Process.h"
- #import "MyMenuCell.h"
- #import "Defaults.h"
- #import "License.h"
- #import "util.h"
- #import "state.h"
-
- @implementation Storm
-
- static int localblank(char *s){
- while (*s && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')) s++;
- return *s? 0 : 1;
- }
-
- static id _status;
- static id _Parrot; /* compiler hated _P ! */
- static id _text, _scroll;
- static id fid = (id)0;
- static int canconvert = 0;
- static id me;
-
-
-
- char *
- path(char *s)
- /*
- * if 's' is in [NXArgv[0]], return [NXArgv[0]]/s.
- * (for looking up internal commands and files in .../Opener.app/...).
- */
- {
- char t[1024], *q, *r;
- static char p[1024];
- extern char **NXArgv;
- *t = '\0';
- sscanf(s,"%s",t);
- if (!*t || *t=='(') return s;
- r = s + strlen(t);
- strcpy(p,*NXArgv);
- if (q=rindex(p,'/'))
- strcpy(q+1,t);
- else
- strcpy(p,t);
- if (access(p,0)==0){
- strcpy(p+strlen(p),r);
- return p;
- }
- return s;
- }
-
- void message(char *fmt, ...) {
- char p[1024];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(p,fmt,ap);
- [_status setStringValue:p];
- [_status display];
- NXPing();
- va_end(ap);
- }
-
- static int eq(char *a, char *b){ return strncmp(a,b,strlen(b))==0; }
-
- static char *localstrindex(char *s, char *t){
- int n = strlen(t);
- if (s) while (*s)
- if (!strncmp(s, t, n))
- return s;
- else
- s++;
- return (char *)0;
- }
-
- void Put(char *fmt, ...) {
- va_list ap;
- char p[1024];
-
- va_start(ap, fmt);
- vsprintf(p, fmt, ap);
- if (Verbose) printf("+ %s\n",p);
- if (_Parrot) [_Parrot puts:p];
- va_end(ap);
- }
-
-
- static char *
- get(id P, char *s, int n) {
- [P gets:s:n];
- if (*s && Verbose) printf("> %s",s);
- return *s? s : (char *)0;
- }
-
- char *
- pgets(char *s, int n) {
- [_Parrot gets:s:n];
- return *s? s : (char *)0;
- }
-
-
- char *
- Flush(char *s) {
- static char t[1024];
- if (_Parrot) return (char *)0;
- while (get(_Parrot,t,sizeof t))
- if (localstrindex(t,s)) return t;
- sleep(1);
- while (get(_Parrot,t,sizeof t))
- if (localstrindex(t,s)) return t;
- return (char *)0;
- }
-
- - enable:(BOOL)b {
- [attachB setIcon:b? "plug" : "unplug"];
- return self;
- }
-
-
-
- - initMatrix {
- // from the nib file, we have the help text; keep a pointer to it.
- _text = helpText = [scrollView docView];
- [_text setDelegate:self];
- [_text setMarginLeft:6.0 right:6.0 top:0.0 bottom:0.0];
- [_text notifyAncestorWhenFrameChanged:YES];
- return self;
- }
-
- - setScrollView:anObject {
- _scroll = scrollView = anObject;
- [self initMatrix];
- return self;
- }
-
- - textWillConvert:textObject fromFont:from toFont:to {
- if (canconvert && strcmp(DefaultFont,[from name])==0 &&
- atof(DefaultFontSize) == [from pointSize]){
- strcpy(DefaultFont,[to name]);
- sprintf(DefaultFontSize,"%f",[to pointSize]);
- fid = to;
- writeDefaults();
- }
- return to;
- }
-
- void
- setText(char *s) {
- static NXPoint origin = {0.0,0.0};
- id w = [_scroll window];
-
- if (!fid){
- fid = [Font newFont:DefaultFont size:atof(DefaultFontSize)];
- }
- canconvert=0;
- [w disableFlushWindow];
- [_text setText:s];
- [_text setSel:0:999999];
- [_text setSelGray:0.0];
- [_text setSelFont:fid];
- [_text selectNull];
- [_text scrollPoint:&origin];
- [_scroll display];
- [[w reenableFlushWindow] flushWindow];
- NXPing();
- canconvert=1;
- }
-
- void openFile(char *s){ /* open 's' in workspace */
- int ok = 0;
- id p = [NXApp appSpeaker];
- char t[512];
-
- sprintf(t,"\nThe file\n %s\nwill open in the workspace.",s);
- setText(t);
- [p setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)];
- [p openFile:s ok:&ok];
- if (!ok) sprintf(t,"\nCouldn't open: %s",s), setText(t);
- }
-
- static int isRTF(char *s) {
- int f = open(s,0);
- if (f > 0){
- char t[128];
- int n = read(f,t,sizeof(t));
- close(f);
- if (n <= 0) return 0;
- return strncmp(t,"{\\rtf",5)==0;
- } else
- return 0;
- }
-
- void
- setFile(char *s) {
- char *p = path(s);
- NXStream *f = NXMapFile(p,NX_READONLY);
- static NXPoint origin = {0.0,0.0};
- id w = [_scroll window];
-
- canconvert=0;
- if (!f) return ;
- [w disableFlushWindow];
-
- if (isRTF(p)){
- [_text setMonoFont:NO];
- [_text readRichText:f];
- } else {
- [_text readText:f];
- [_text setSel:0:999999];
- [_text setSelGray:0.0];
- if (!fid)
- fid = [Font newFont:DefaultFont size:atof(DefaultFontSize)];
- [_text setSelFont:fid];
- [_text selectNull];
- canconvert=1;
- }
- NXCloseMemory(f,NX_FREEBUFFER);
- [_text scrollPoint:&origin];
- [_scroll display];
- [[w reenableFlushWindow] flushWindow];
- }
-
- - showHelp:sender {
- setFile("info");
- return self;
- }
-
- #define Case break; case
-
- static void squishRtn(char *s){
- char *p = s;
-
- while (*p = *s++)
- if (*p != '\r') ++p;
- }
-
- static char *
- getLine(char *s, char *t){ /* read ...\n from s into t; return new s */
- char *p = t;
- *t = '\0';
- squishRtn(s);
- while (*s && *s != '\n') *p++ = *s++;
- if (*s == '\n') *p++ = *s++;
- *p++ = '\0';
- if (*t == '\0') return (char *)0;
- if (Verbose) printf("- %s",t);
- return s;
- }
-
- - processOutput:(char *)s {
- static char prev[8192]="";
- char t[1024], *p=prev;
-
- strcat(prev,s); s = t;
- while ((p=getLine(p,s)) &&
- (index(s,'\n') || strcmp(s+strlen(s)-2,": ")==0 ||
- strcmp(s+strlen(s)-1,":")==0))
- execState(0,s);
- strcpy(prev,localblank(s)?s:"");
- return self;
- }
-
- void Command(char *s) {
- if (!_Parrot) {
- substr(s,"$Site",Site);
- _Parrot = [Process new:s delegate:me];
- }
- }
-
- - click:sender {
- id c = [[browser matrixInColumn:[browser lastColumn]] selectedCell];
- if ([c isLeaf])
- [c click:self];
- return self;
- }
-
- - click2:sender {
- return self;
- }
-
- - ensurelogin {
- //if (!_Parrot) [self login:self];
- return self;
- }
-
-
- int ensurelogin(void){
- [me ensurelogin];
- return _Parrot? 1 : 0;
- }
-
- - login:sender {
- if (_Parrot) [_Parrot free]; P = _Parrot = (id)0;
- _status = status;
- [self setFetch];
- ReadState(path("menus"));
- [browser setDelegate:self];
- [browser setCellPrototype:[[MyMenuCell alloc] init]];
- [browser loadColumnZero];
- [browser setAction:@selector(click:)];
- [browser setDoubleAction:@selector(click2:)];
- [browser setTarget:self];
- [attachB setIcon:"plug"];
- runState("");
- return self;
- }
-
- - logout:sender {
- if (P && _Parrot) setState("Detach"), runState("");
- if (P) [P terminate:self];
- _Parrot = P = (id)0;
- [self enable:NO];
- [attachB setIcon:"unplug"];
- message("not connected.");
- return self;
- }
-
- void
- logout(void){
- [me logout:me];
- }
-
- - attach:sender {
- if (eq((char *)[sender icon],"unplug")){
- [self login:sender];
- } else {
- [self logout:sender];
- }
- return self;
- }
-
- /*
- * the buttons and commands to run at startup time.
- */
- id Fetch[NumFetch];
-
- int FetchSelected = -1;
-
- - setFetch {
- int i;
- Fetch[0] = fetch1;
- Fetch[1] = fetch2;
- Fetch[2] = fetch3;
- for (i=0;i<NumFetch;i++) [self setFetchText:i:FetchText[i]];
- return self;
- }
-
- - setFetchText:(int)i:(char *)s {
- [Fetch[i] setStringValue:s];
- strcpy(FetchText[i],s);
- [Fetch[i] display];
- return self;
- }
-
- - setFetchText:(char *)s {
- if (FetchSelected >= 0)
- [self setFetchText:FetchSelected:s];
- return self;
- }
-
- void
- setFetchText(char *s) {
- [me setFetchText:s];
- }
-
- - setFetch:(int)i:(int)state {
- [Fetch[i] setBackgroundGray:state?1.0:.666];
- if (state) [self setFetchText:i:""];
- else [Fetch[i] display];
- return self;
- }
-
- - hitRadio:sender {
- int i;
- int n = [sender selectedRow], state = [[sender selectedCell] state];
- [self setFetch:n:state];
- FetchSelected = state? n : -1;
- for (i=0; i<NumFetch; i++){
- if (i != n || !state){
- [[sender cellAt:i:0] setState:0];
- [self setFetch:i:0];
- }
- }
- [sender display];
- return self;
- }
-
- void fetchReports(void ) {
- int i;
- char buf[80000], *p = buf;
- while (pgets(buf,1024) && !localstrindex(buf,curMenuLast())) ;
- *buf = '\0';
- for (i=0;i<NumFetch;i++){
- if (!localblank(FetchText[i])){
- message("%s. . .",FetchText[i]);
- fetchReport(FetchText[i],p);
- if (p[0]){
- p += strlen(p);
- if (i < (NumFetch-1))
- strcpy(p,"\n===============================\n");
- p += strlen(p);
- }
- }
- }
- squishRtn(buf);
- squishwhite(buf);
- if (*buf) setText(buf);
- message("connected!");
- }
-
- - setSite:thing {
- openDefaults();
- site = thing;
- [site setTitle:Site];
- return self;
- }
-
- - hitSite:sender {
- char *s = (char *)[[sender selectedCell] title];
- strcpy(Site,s);
- writeDefaults();
- return self;
- }
-
- /*
- * telnet:
- */
-
- - copyString:(char *)s {
- id p = [Pasteboard new];
- [p declareTypes:&NXAsciiPboard num:1 owner:self];
- [p writeType:NXAsciiPboard data:s length:strlen(s)];
- return self;
- }
-
- - launchTerminal:(char *)program {
- id p = [NXApp appSpeaker];
- port_t t = NXPortFromName("Terminal",NULL);
- int ok;
- if (t==PORT_NULL) return self;
- [p setSendPort:t];
- [self copyString:program];
- (void)[p msgPaste:&ok];
- return self;
- }
-
- - telnet:sender {
- char p[1024];
- sprintf(p,"telnet %s 3000\n",Site);
- [self launchTerminal:p];
- return self;
- }
-
- - sendComments:sender {
- return self;
- }
-
- - print:sender {
- static int p = 0;
- if (!p){
- p++;
- [[NXApp printInfo] setScalingFactor:.9];
- }
- return [_text printPSCode:sender];
- }
-
- - pageLayout:sender {
- return [NXApp runPageLayout:sender];
- }
-
- + new {
- me = self = [[Storm alloc] init];
- return self;
- }
-
- - free {
- [self logout:self];
- return [super free];
- }
-
-
- - appDidInit:sender {
- openDefaults();
- if (FirstUse()) [license show:self];
- [attachB performClick:sender];
- return self;
- }
-
- - appWillTerminate:sender {
- [self logout:self];
- System("/bin/rm -rf /tmp/W_maps /tmp/W_scratch &");
- writeDefaults();
- return self;
- }
-
- - (int)browser:sender fillMatrix:matrix inColumn:(int)column {
- char *s = "Main";
- if (column>0){
- id c;
- c = [[browser matrixInColumn:[browser lastColumn]] selectedCell];
- s = [c get];
- }
- setMenu(s);
- return numItem(s);
- }
-
- - browser:sender loadCell:c atRow:(int)row inColumn:(int)column {
- [c setStringValueNoCopy:(void *)curMenuItem(row)];
- return self;
- }
-
- - browserDidScroll:sender {
- static int pc = -1;
- int c = [browser firstVisibleColumn];
- ensurelogin();
- if (pc == c) return self;
- pc = c;
- if (c == 0) Put("m\n"), Flush("Change scroll"), setMenu("Main");
- else
- [[[browser matrixInColumn:0] selectedCell] click:self];
- return self;
- }
-
-
- @end
-